package com.xuecheng.orders.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.xuecheng.base.util.QRCodeUtil;
import com.xuecheng.orders.config.AliPayProperties;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @author 勾新杰
 * @version 1.0
 * @description: 支付测试接口
 * @date 2025/2/27 17:42
 */
@Slf4j
@Controller
@RequiredArgsConstructor
@RequestMapping("/alipay-test")
@Api(tags = "支付测试管理接口")
public class PayTestController {

    private final AlipayClient alipayClient;

    private final AliPayProperties aliPayProperties;

    @GetMapping("/pay")
    @ApiOperation("支付宝支付测试")
    public void createOrder(HttpServletResponse response) throws AlipayApiException {
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo("70501111111S001111115"); // 订单号
        model.setTotalAmount("90.00"); // 金额
        model.setSubject("支付测试"); // 标题
        model.setProductCode("QUICK_WAP_WAY"); // 产品码
        request.setBizModel(model);
        request.setReturnUrl("http://51xuecheng.cn"); // 支付成功后跳转的页面，用户跳转的页面
        request.setNotifyUrl("http://5e9a8a5e.cpolar.io/orders/alipay-test/pay-notify"); // 支付成功后异步通知的url，通知的是商家
        AlipayTradeWapPayResponse payResponse = alipayClient.pageExecute(request, "POST");
        if (payResponse.isSuccess()) {
            response.setContentType("text/html;charset=UTF-8");
            try {
                // 获取返回的表单返回给前端
                String form = payResponse.getBody();
                System.out.println(form);
                response.getWriter().write(form);
                response.getWriter().flush();
                response.getWriter().close();
            } catch (IOException e) {
                log.error("Failed to write response: " + e.getMessage());
            }
        } else {
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            try {
                response.getWriter().write("支付请求失败，请稍后再试。");
            } catch (IOException e) {
                log.error("Failed to write response: " + e.getMessage());
            }
        }
    }

    @GetMapping("/query/{outTradeNo}")
    @ApiOperation("支付宝订单查询测试")
    public void queryOrder(@PathVariable String outTradeNo) throws AlipayApiException {
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        model.setOutTradeNo(outTradeNo);
        request.setBizModel(model);
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());
        if (response.isSuccess()) {
            System.out.println("订单查询成功");
        }
    }

    @GetMapping("/refund")
    @ApiOperation("支付宝退款测试")
    public void refundOrder() throws AlipayApiException {
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        model.setOutTradeNo("70501111111S001111118"); // 订单号
        model.setRefundAmount("20.12"); // 退款金额
        model.setRefundReason("正常退款"); // 退款原因
        model.setOutRequestNo("HZ01RF001"); // 退款请求号，部分退款时必须要设置
        request.setBizModel(model);
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());
        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
    }

    /**
     * 支付成功后异步通知
     *
     * @param request  请求
     * @param response 响应
     */
    @PostMapping("/pay-notify")
    @ApiOperation("支付宝支付成功后异步通知")
    public void payNotify(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < values.length; i++) {
                if (i == values.length - 1) builder.append(values[i]);
                else builder.append(values[i]).append(",");
            }
            params.put(name, builder.toString());
        }
        boolean verify_result;
        try {
            verify_result = AlipaySignature.rsaCheckV1(params, aliPayProperties.getAlipayPublicKey(), aliPayProperties.getCharset(), aliPayProperties.getSignType());
        } catch (AlipayApiException e) {
            log.error("Failed to verify signature: " + e.getMessage());
            throw new RuntimeException("Failed to verify signature.");
        }
        if (verify_result) {
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
            String trade_no = new String(request.getParameter("trade_no").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
            String trade_status = new String(request.getParameter("trade_status").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
            if (trade_status.equals("TRADE_FINISHED")) {// 交易结束
                log.debug("交易结束，订单交易号：{}，订单号：{}，交易状态：{}", trade_no, out_trade_no, trade_status);
            } else if (trade_status.equals("TRADE_SUCCESS")) {// 交易成功
                log.debug("交易成功，订单交易号：{}，订单号：{}，交易状态：{}", trade_no, out_trade_no, trade_status);
            }
            try {
                response.getWriter().write("success");
            } catch (IOException e) {
                log.error("Failed to write response: " + e.getMessage());
                throw new RuntimeException("Failed to write response.");
            }
        } else {
            try {
                response.getWriter().write("fail");
            } catch (IOException e) {
                log.error("Failed to write response: " + e.getMessage());
                throw new RuntimeException("Failed to write response.");
            }
        }
    }

    public static void main(String[] args) {
        System.out.println(QRCodeUtil.createQRCode("http://5e9a8a5e.cpolar.io/orders/alipay-test/pay", 200, 200));
    }
}
